package com.cash.loan.modular.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.cash.loan.common.entity.UserInfo;
import com.cash.loan.common.result.PageResult;
import com.cash.loan.common.upload.QiniuService;
import com.cash.loan.common.util.PageBeanUtil;
import com.cash.loan.common.util.RedisUtil;
import com.cash.loan.config.properties.CacheTimeProperties;
import com.cash.loan.core.util.MD5Util;
import com.cash.loan.modular.cash.model.LoanProduct;
import com.cash.loan.modular.cash.transfer.vo.ProductListVo;
import com.cash.loan.modular.user.dao.CashUserLoginMapper;
import com.cash.loan.modular.user.dao.CashUserMapper;
import com.cash.loan.modular.user.model.CashUser;
import com.cash.loan.modular.user.model.CashUserLogin;
import com.cash.loan.modular.user.service.UserService;
import com.cash.loan.modular.user.transfer.dto.UserEnum;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;

import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @author Administrator
 * @Date 2018-07-09 16:13
 */
@Service
public class UserServiceImpl implements UserService {

    private static List<String> names = new ArrayList<>();

    static {
        names.add("挖财");
        names.add("富贵");
        names.add("来财");
        names.add("好运");
        names.add("赚赚");
    }

    private static final String CACHE_PREFIX = "message:code_";

    @Autowired
    private CashUserLoginMapper userLoginMapper;

    @Autowired
    private CashUserMapper userMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private QiniuService qiniuService;

    @Autowired
    private CacheTimeProperties cacheTimeProperties;

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Map<String, String> register(String phone, String password, String ip, String regFrom) {

        //新增user_login表数据
        CashUserLogin userLogin = new CashUserLogin();
        userLogin.setPassword(MD5Util.encrypt(password));
        userLogin.setUserFlag(1L);
        userLogin.setPhone(phone);
        userLogin.setIp(ip);
        userLoginMapper.insert(userLogin);

        //新增user表数据
        CashUser cashUser = new CashUser();
        cashUser.setPhone(phone);
        Random random = new Random();
        int index = random.nextInt(names.size());
        cashUser.setNickName(names.get(index % names.size()) + phone.substring(7, 11));
        if (StringUtils.isNoneBlank(regFrom)) {
            cashUser.setRegFrom(regFrom);
        }
        cashUser.setUserId(userLogin.getId());
        userMapper.insert(cashUser);

        //删除短信验证码缓存
        redisUtil.delete(CACHE_PREFIX + phone);
        //注册成功
        UserInfo userInfo = new UserInfo();
        userInfo.setId(cashUser.getId());
        userInfo.setUserId(cashUser.getUserId());
        userInfo.setPhone(phone);
        return productToken(userInfo);
    }

    @Override
    public Boolean isExistedUser(String phone) {
        Integer count = userLoginMapper.isExistByPhone(phone);
        if (count != 1) {
            return false;
        }
        return true;
    }

    @Override
    public UserInfo checkPhoneAndPwd(String phone, String password, String ip) {
        Integer count = userLoginMapper.checkPhoneAndPwd(phone, MD5Util.encrypt(password));
        if (count != 1) {
            return null;
        }
        UserInfo userInfo = userLoginMapper.getUserInfo(phone);
        CashUserLogin userLogin = new CashUserLogin();
        userLogin.setIp(ip);
        userLogin.setId(userInfo.getUserId());
        userLoginMapper.updateById(userLogin);
        userInfo.setPhone(phone);
        return userInfo;
    }

    @Override
    public Map<String, String> productToken(UserInfo userInfo) {
        String userInfoStr = JSONObject.toJSONString(userInfo);
        String token = productTokenName();
        redisUtil.set(token, userInfoStr, cacheTimeProperties.getToken());
        Map<String, String> result = new HashMap<>(1);
        result.put("token", token);
        return result;
    }

    @Override
    public String productTokenName() {
        String token = IdWorker.getId() + "";
        try {
            token = Base64Utils.encodeToString(token.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        token = token.replace("=", "");
        return token;
    }

    @Override
    public Map<String, Object> getUserInfo(Long id) {
        Map<String, Object> userDetailInfo = userMapper.getUserInfo(id);
        if (userDetailInfo == null || userDetailInfo.isEmpty()) {
            return new HashMap<>(2);
        }
        userDetailInfo = dealUserDetailInfo(userDetailInfo);
        userDetailInfo.put("imgUrl", qiniuService.getUrl((String) userDetailInfo.get("imgUrl")));
        Long creditCardFlag = (Long) userDetailInfo.get("creditCardFlag");
        if (creditCardFlag == 0) {
            userDetailInfo.put("creditCardFlag", "未知");
        }
        if (creditCardFlag == 1) {
            userDetailInfo.put("creditCardFlag", "有");
        }
        if (creditCardFlag == 2) {
            userDetailInfo.put("creditCardFlag", "无");
        }
        return userDetailInfo;
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Boolean updatePassword(Long id, String password) {
        CashUserLogin userLogin = new CashUserLogin();
        userLogin.setId(id);
        userLogin.setPassword(MD5Util.encrypt(password));
        userLoginMapper.updateById(userLogin);
        return true;
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Boolean updateUser(String type, String content, Long id) {
        CashUser cashUser = setCashUserByType(type, content);
        cashUser.setId(id);
        userMapper.updateById(cashUser);
        return true;
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Boolean saveUserLoginInfo(String deviceId, String ip) {
        int count = userLoginMapper.isExistDeviceId(deviceId);
        if (count >= 1) {
            return true;
        }
        CashUserLogin userLogin = new CashUserLogin();
        userLogin.setDeviceId(deviceId);
        userLogin.setUserFlag(0L);
        userLogin.setIp(ip);
        userLoginMapper.insert(userLogin);
        return true;
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Boolean updatePasswordByPhone(String phone, String password) {
        password = MD5Util.encrypt(password);
        userLoginMapper.updatePasswordByPhone(phone, password);
        return true;
    }

    @Override
    public PageResult<ProductListVo> getUserApplyList(Integer currentPage, Integer pageSize, Long visitId) {
        PageHelper.startPage(currentPage, pageSize);
        List<LoanProduct> productList = userLoginMapper.getProductByVisitId(visitId);

        if (productList == null || productList.size() == 0) {
            return new PageResult<>();
        }

        List<ProductListVo> productListVoList = new ArrayList<>();
        productList.stream().forEach(loanProduct -> {
            ProductListVo listVo = new ProductListVo();
            listVo.setProductName(loanProduct.getProductName());
            listVo.setProductId(loanProduct.getId());
            listVo.setProductIconUrl(qiniuService.getUrl(loanProduct.getProductIconUrl()));
            listVo.setProductSellPoint(loanProduct.getProductSellPoint());
            listVo.setDayLoanRate(loanProduct.getDayLoanRate());
            listVo.setLoanTerm(loanProduct.getMinLoanTerm() + "-" + loanProduct.getMaxLoanTerm() + "天");
            listVo.setMaxLoanAmount(loanProduct.getMaxLoanAmount().toString());
            productListVoList.add(listVo);
        });
        PageResult pageResult = PageBeanUtil.toPageResult(productList);
        pageResult.setDataList(productListVoList);
        return pageResult;
    }

    private CashUser setCashUserByType(String type, String content) {
        CashUser cashUser = new CashUser();
        if (UserEnum.NICK_NAME.getName().equals(type)) {
            if (StringUtils.isNoneBlank()) {
                cashUser.setNickName(content);
            }
        }
        if (UserEnum.REAL_NAME.getName().equals(type)) {
            if (StringUtils.isNoneBlank()) {
                cashUser.setRealName(content);
            }
        }
        if (UserEnum.ID_CARD.getName().equals(type)) {
            if (StringUtils.isNoneBlank()) {
                cashUser.setIdCard(content);
            }
        }
        if (UserEnum.AGE.getName().equals(type)) {
            if (StringUtils.isNoneBlank()) {
                cashUser.setAge(content);
            }
        }
        if (UserEnum.JOB_TYPE.getName().equals(type)) {
            if (StringUtils.isNoneBlank()) {
                cashUser.setJobType(content);
            }
        }
        if (UserEnum.CITY.getName().equals(type)) {
            if (StringUtils.isNoneBlank()) {
                cashUser.setCity(content);
            }
        }
        if (UserEnum.CREDIT_CARD_FLAG.getName().equals(type)) {
            if (StringUtils.isNoneBlank()) {
                cashUser.setCreditCardFlag(Long.valueOf(content));
            }
        }
        return cashUser;
    }

    private Map<String, Object> dealUserDetailInfo(Map<String, Object> userDetailInfo) {
        if (userDetailInfo.get(UserEnum.IMAGE_URL.getName()) == null) {
            userDetailInfo.put("imgUrl", "");
        }
        if (userDetailInfo.get(UserEnum.NICK_NAME.getName()) == null) {
            userDetailInfo.put("nickName", "");
        }
        if (userDetailInfo.get(UserEnum.REAL_NAME.getName()) == null) {
            userDetailInfo.put("realName", "");
        }
        if (userDetailInfo.get(UserEnum.ID_CARD.getName()) == null) {
            userDetailInfo.put("idCard", "");
        }
        if (userDetailInfo.get(UserEnum.AGE.getName()) == null) {
            userDetailInfo.put("age", 0);
        }
        if (userDetailInfo.get(UserEnum.JOB_TYPE.getName()) == null) {
            userDetailInfo.put("jobType", "");
        }
        if (userDetailInfo.get(UserEnum.CITY.getName()) == null) {
            userDetailInfo.put("city", "");
        }
        if (userDetailInfo.get(UserEnum.CREDIT_CARD_FLAG.getName()) == null) {
            userDetailInfo.put("creditCardFlag", 0);
        }
        return userDetailInfo;
    }
}
